import mongoose, { Schema, Document } from 'mongoose';

/**
 * 告警严重程度
 */
export enum AlertSeverity {
  CRITICAL = 'critical',   // 严重
  WARNING = 'warning',     // 警告
  INFO = 'info',          // 信息
}

/**
 * 告警状态
 */
export enum AlertStatus {
  FIRING = 'firing',       // 触发中
  RESOLVED = 'resolved',   // 已解决
  SILENCED = 'silenced',   // 已静默
  ACKNOWLEDGED = 'acknowledged', // 已确认
}

/**
 * LLM 分析结果
 */
export interface ILLMAnalysis {
  isNoise: boolean;                    // 是否是噪音告警
  confidence: number;                  // 置信度 0-1
  priority: 'high' | 'medium' | 'low'; // AI 评估的优先级
  rootCause?: string;                  // 根因分析
  suggestedActions: string[];          // 建议的处理方案
  tags: string[];                      // 自动生成的标签
  relatedAlerts?: string[];            // 关联告警 ID
  analyzedAt: Date;                    // 分析时间
  model?: string;                      // 使用的 LLM 模型
}

/**
 * 告警处理记录
 */
export interface IAlertAction {
  actionType: 'acknowledge' | 'silence' | 'resolve' | 'comment' | 'assign';
  userId: mongoose.Types.ObjectId;
  userName: string;
  comment?: string;
  timestamp: Date;
}

/**
 * 告警接口定义
 */
export interface IAlert extends Document {
  _id: mongoose.Types.ObjectId;

  // Prometheus 原始数据
  fingerprint: string;              // Alertmanager fingerprint（唯一标识）
  alertname: string;                // 告警名称
  labels: Record<string, string>;   // 标签（instance, job, severity 等）
  annotations: Record<string, string>; // 注释（summary, description 等）

  // 告警状态
  status: AlertStatus;
  severity: AlertSeverity;
  startsAt: Date;                   // 开始时间
  endsAt?: Date;                    // 结束时间
  updatedAt: Date;                  // 更新时间

  // LLM 智能分析
  llmAnalysis?: ILLMAnalysis;

  // 处理信息
  assignedTo?: mongoose.Types.ObjectId;  // 分配给谁
  ticketId?: mongoose.Types.ObjectId;    // 关联的工单 ID
  actions: IAlertAction[];               // 处理历史

  // 上下文信息（用于 LLM 分析）
  context?: {
    historicalData?: any;          // 历史数据
    relatedMetrics?: any;          // 相关指标
    businessContext?: string;      // 业务上下文
  };

  createdAt: Date;
}

/**
 * 告警数据模型
 */
const AlertSchema = new Schema<IAlert>(
  {
    fingerprint: {
      type: String,
      required: true,
      unique: true,
      index: true,
    },
    alertname: {
      type: String,
      required: true,
      index: true,
    },
    labels: {
      type: Map,
      of: String,
      default: {},
    },
    annotations: {
      type: Map,
      of: String,
      default: {},
    },
    status: {
      type: String,
      enum: Object.values(AlertStatus),
      default: AlertStatus.FIRING,
      index: true,
    },
    severity: {
      type: String,
      enum: Object.values(AlertSeverity),
      required: true,
      index: true,
    },
    startsAt: {
      type: Date,
      required: true,
      index: true,
    },
    endsAt: {
      type: Date,
      default: null,
    },
    updatedAt: {
      type: Date,
      default: Date.now,
    },

    // LLM 分析结果
    llmAnalysis: {
      isNoise: {
        type: Boolean,
        default: null,
      },
      confidence: {
        type: Number,
        min: 0,
        max: 1,
        default: null,
      },
      priority: {
        type: String,
        enum: ['high', 'medium', 'low'],
        default: null,
      },
      rootCause: {
        type: String,
        default: null,
      },
      suggestedActions: {
        type: [String],
        default: [],
      },
      tags: {
        type: [String],
        default: [],
        index: true,
      },
      relatedAlerts: {
        type: [String],
        default: [],
      },
      analyzedAt: {
        type: Date,
        default: null,
      },
      model: {
        type: String,
        default: null,
      },
    },

    // 处理信息
    assignedTo: {
      type: Schema.Types.ObjectId,
      ref: 'User',
      default: null,
      index: true,
    },
    ticketId: {
      type: Schema.Types.ObjectId,
      ref: 'Ticket',
      default: null,
      index: true,
    },
    actions: {
      type: [
        {
          actionType: {
            type: String,
            enum: ['acknowledge', 'silence', 'resolve', 'comment', 'assign'],
            required: true,
          },
          userId: {
            type: Schema.Types.ObjectId,
            ref: 'User',
            required: true,
          },
          userName: {
            type: String,
            required: true,
          },
          comment: {
            type: String,
            default: null,
          },
          timestamp: {
            type: Date,
            default: Date.now,
          },
        },
      ],
      default: [],
    },

    // 上下文信息
    context: {
      historicalData: {
        type: Schema.Types.Mixed,
        default: null,
      },
      relatedMetrics: {
        type: Schema.Types.Mixed,
        default: null,
      },
      businessContext: {
        type: String,
        default: null,
      },
    },
  },
  {
    timestamps: true,
    versionKey: false,
  }
);

/**
 * 索引定义
 */
AlertSchema.index({ fingerprint: 1 }, { unique: true });
AlertSchema.index({ status: 1, severity: 1 });
AlertSchema.index({ startsAt: -1 });
AlertSchema.index({ 'llmAnalysis.isNoise': 1, status: 1 });
AlertSchema.index({ 'llmAnalysis.priority': 1, status: 1 });
AlertSchema.index({ 'llmAnalysis.tags': 1 });
AlertSchema.index({ assignedTo: 1, status: 1 });

/**
 * 实例方法：添加处理记录
 */
AlertSchema.methods.addAction = function (
  actionType: string,
  userId: mongoose.Types.ObjectId,
  userName: string,
  comment?: string
) {
  this.actions.push({
    actionType,
    userId,
    userName,
    comment,
    timestamp: new Date(),
  });
  return this.save();
};

/**
 * 实例方法：更新 LLM 分析结果
 */
AlertSchema.methods.updateLLMAnalysis = function (analysis: Partial<ILLMAnalysis>) {
  this.llmAnalysis = {
    ...this.llmAnalysis,
    ...analysis,
    analyzedAt: new Date(),
  };
  return this.save();
};

/**
 * 静态方法：查询未分析的告警
 */
AlertSchema.statics.findUnanalyzed = function (limit = 10) {
  return this.find({
    status: AlertStatus.FIRING,
    'llmAnalysis.analyzedAt': null,
  })
    .sort({ startsAt: -1 })
    .limit(limit);
};

/**
 * 静态方法：查询噪音告警
 */
AlertSchema.statics.findNoiseAlerts = function (startDate: Date, endDate: Date) {
  return this.find({
    'llmAnalysis.isNoise': true,
    startsAt: { $gte: startDate, $lte: endDate },
  }).sort({ startsAt: -1 });
};

export default mongoose.model<IAlert>('Alert', AlertSchema);
